package com.self.admin.aspect;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.self.admin.model.SysUserLog;
import com.self.admin.service.SysUserLogService;
import com.self.common.aspect.WebLogAspect;
import com.self.common.constant.CommonConstants;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.annotation.Order;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;

/**
 * @version v1.0
 * @ClassName: SysOperatAspect
 * @Description:
 * @Author: Mac
 * @Date: 2022/6/5 14:28
 */
@Aspect
@Component
@Order(1)
@Slf4j
public class SysOperatLogAspect {

    @Autowired
    private SysUserLogService sysUserLogService;

    @Pointcut("execution(* com.self.admin.controller.*.*(..))")
    public void point(){}


    @Around("point()")
    public Object proccess(ProceedingJoinPoint joinPoint)throws Throwable{
        long start = System.currentTimeMillis() ;
        Object obj = joinPoint.proceed(joinPoint.getArgs());
        long end = System.currentTimeMillis() ;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String url = request.getRequestURL().toString();
        SysUserLog userLog = new SysUserLog();
        // 获取方法
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        // 获取类的名称
        String targetClassName = joinPoint.getTarget().getClass().getName();
        Method method = signature.getMethod();
        // 因为我们会使用Swagger 这工具，我们必须在方法上面添加@ApiOperation(value="")该注解
        // 获取ApiOperation
        ApiOperation annotation = method.getAnnotation(ApiOperation.class);
        userLog.setDescription(annotation==null ? "no desc":annotation.value());
        userLog.setMethod(targetClassName+"."+method.getName());
        userLog.setGroup(userLog.getDescription());
        // 获取安全的上下文
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        userLog.setUserId(authentication == null || CommonConstants.ANONYMOUS.equalsIgnoreCase(authentication.getPrincipal().toString())? CommonConstants.ANONYMOUS_ID:Long.valueOf(authentication.getPrincipal().toString()));
        userLog.setCreated(new Date());
        userLog.setIp(request.getRemoteAddr());
        userLog.setTime((end-start)/1000);
        Object targetParams = WebLogAspect.getTargetParams(method, joinPoint.getArgs());
        userLog.setParams(targetParams != null? JSONObject.toJSONString(targetParams):null);
        sysUserLogService.save(userLog);
        return obj;
    }


}
